/*
 * @Description: 新建检测方案 - 设置检测字段
 * @Author: Rfan
 * @Date: 2022-10-10 09:52:08
 * @LastEditTime: 2022-10-22 17:24:03
 */

import { forwardRef, Key, Ref, useEffect, useImperativeHandle, useState } from 'react';
import { Button, Divider, Input, message, Select, Space, Table, Tabs, Typography } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import cs from 'classnames';
import classnames from 'classnames/bind';
import { v4 as uuidv4 } from 'uuid';
import { fetchMetadata } from '@/api/metadata';
import { isNullObj, jsonClone } from '@/utils';
import { delItemById, editItemById, selectItemByKey } from '@/utils/list';
import { useArchivesDetectionContext } from '../../../../contexts/ArchivesDetectionContext';
import { useAddPlanDialogContext } from '../contexts/AddPlanDialogContext';
import { QUERY_METADATA_ALL } from '@/view/system/Metadata/constants';
import type { ILevel } from '@/interfaces/archiveType';
import styles from '../styles/main.module.scss';
import { CheckProps } from '@/view/system/ArchivesDetection/dictionaries';

const cx = classnames.bind(styles);
const { TabPane } = Tabs;
const { Column } = Table;
const { Option } = Select;

class CheckItem {
  key: string;

  field: string = '';

  constructor() {
    this.key = uuidv4();
  }
}

export interface ITableData {
  key: Key;
  field: string;
}

export interface ILevelFieldCheck {
  level: number;
  levelNum?: number;
  levelName: string;
  fieldList: string[];
}

const FieldCheck = forwardRef((props: any, ref: Ref<unknown>) => {
  const { levelListWithoutERecord: levelList, selectAT } = useArchivesDetectionContext();
  const { levelFieldList, setLevelFieldList, currentRuleInfo, getPropertyRules } =
    useAddPlanDialogContext();

  // 当前选中的tab
  const [currentTab, setCurrentTab] = useState<string>('');
  // 各层级元数据
  const [levelMetadata, setLevelMetadata] = useState<any>({});
  // 表格内容
  const [initTable, setInitTable] = useState<ITableData[]>([]);
  // 新增的表头字段
  const [name, setName] = useState('');

  useImperativeHandle(ref, () => ({
    submit: onFinish
  }));

  /**
   * @description: 获取到规则后回写
   */
  useEffect(() => {
    if (currentRuleInfo && !isNullObj(currentRuleInfo) && levelFieldList.length <= 0) {
      const propRules = getPropertyRules(CheckProps.Authenticity)?.rules || [];
      const levelRulesList = selectItemByKey(1, propRules, 'ruleType')?.rules || [];
      const levelFieldData = levelRulesList.map((item: any) => {
        const fieldList = item.rules.map((rule: any) => rule.field);
        delete item.rules;
        return { ...item, fieldList };
      });
      setLevelFieldList(levelFieldData);
    }
  }, [currentRuleInfo]);

  useEffect(() => {
    if (levelList?.length > 0) {
      const highestLevel = levelList.find((level: ILevel) => level.levelNum === 1);
      setCurrentTab(`${highestLevel?.level}`);

      // 获取档案类型下所有层级
      levelList.forEach((item: any) => {
        const { level } = item;
        const fieldQuery = {
          metadataFieldType: QUERY_METADATA_ALL,
          coordinate: {
            atType: selectAT.atType,
            atCode: selectAT.atCode,
            level
          }
        };
        fetchMetadata(fieldQuery).then((res: any) => {
          setLevelMetadata((state: any) => ({
            ...state,
            [level]: res.data.filter((item: any) => item.field_kind !== 0)
          }));
        });
      });
    }
  }, [levelList]);

  useEffect(() => {
    if (currentTab) {
      const currentData = levelFieldList.find(
        (item: any) => item.level === parseInt(currentTab, 10)
      );
      setInitTable(
        currentData?.fieldList?.map((field: string, idx: number) => ({
          field,
          key: field + idx
        })) || []
      );
    }
  }, [currentTab]);

  useEffect(() => {
    if (!isNullObj(levelMetadata) && initTable.length === 0) {
      const currentData = levelFieldList.find(
        (item: any) => item.level === parseInt(currentTab, 10)
      );
      setInitTable(
        currentData?.fieldList?.map((field: string, idx: number) => ({
          field,
          key: field + idx
        })) || []
      );
    }
  }, [levelMetadata]);

  /**
   * @description: tab切换
   * @param {string} key 选中的tab的key
   */
  const tabsChange = (key: string) => {
    saveTableForm();
    setCurrentTab(key);
  };

  /**
   * @description: 保存当前层级填入字段
   */
  const saveTableForm = () => {
    const newState: ILevelFieldCheck[] = jsonClone(levelFieldList);
    const currentLevel: ILevel =
      selectItemByKey(parseInt(currentTab, 10), levelList, 'level') || {};
    const { level, levelNum, levelName } = currentLevel;
    const fieldList: string[] = Array.from(
      new Set(initTable.map((item) => item.field).filter((str) => str))
    );
    if (fieldList.length > 0) {
      if (newState.length > 0) {
        let flag: boolean = false;
        newState.forEach((item) => {
          if (item.level === currentLevel.level) {
            item.fieldList = fieldList;
            flag = true;
          }
        });
        // 如果循环完没有当前层级
        if (!flag) {
          newState.push({
            level,
            levelNum,
            levelName,
            fieldList
          });
        }
      } else {
        newState.push({
          level,
          levelNum,
          levelName,
          fieldList
        });
      }
      setLevelFieldList(newState);
      return newState;
    }
  };

  /**
   * @description: 添加选项输入框变化事件
   * @param {any} evt 输入事件
   */
  const onNameChange = (evt: any) => {
    setName(evt.target.value);
  };

  /**
   * @description: 新增一个选项
   * @param {any} evt 按钮点击事件
   */
  const addItem = (evt: any) => {
    evt.preventDefault();
    if (name) {
      if (!selectItemByKey(name, levelMetadata[currentTab], 'field_name')) {
        setLevelMetadata((state: any) => ({
          ...state,
          [currentTab]: [{ field_name: name, field_desc: name }, ...state[currentTab]]
        }));
      } else {
        message.warning('字段已存在');
      }
      setName('');
    }
  };

  /**
   * @description: 保存单元格操作选择的内容
   * @param {any} row
   */
  const handleSave = ({ key, name }: any) => {
    setInitTable((state) => editItemById(key, { key, field: name }, state, 'key'));
  };

  /**
   * @description: 清空全部数据
   */
  const clearAll = () => {
    setInitTable([]);
  };

  /**
   * @description: 删除当前条目
   * @param {string} key
   */
  const deleteItem = (key: string) => {
    setInitTable(delItemById(key, initTable, 'key'));
  };

  /**
   * @description: 提交所选元数据
   */
  const onFinish = () => {
    saveTableForm();
  };

  const operations = (
    <Space>
      <Button
        size="small"
        onClick={() => {
          setInitTable((state) => [...state, new CheckItem()]);
        }}
      >
        增加表头
      </Button>
      <Button
        size="small"
        onClick={() => {
          clearAll();
        }}
      >
        清空
      </Button>
    </Space>
  );

  return (
    <div className={cs(cx('step-pane'), cx('field-check'))}>
      <Tabs activeKey={currentTab} tabBarExtraContent={operations} onChange={tabsChange}>
        {levelList.map((level: ILevel) => (
          <TabPane tab={level.levelName} key={level.level}>
            <Table dataSource={initTable} size="small" pagination={false} bordered>
              <Column
                title="序号"
                key="idCol"
                align="center"
                render={(_val, _record, idx) => `${idx + 1}`}
              />
              <Column
                title="设置检测字段"
                dataIndex="field"
                key="field"
                align="center"
                render={(val, record: ILevel) => (
                  <Select
                    value={val}
                    style={{ width: 200 }}
                    placeholder="请选接收检测元数据"
                    size="small"
                    dropdownRender={(menu) => (
                      <>
                        <Space align="center" style={{ padding: '0 8px 4px' }}>
                          <Input placeholder="手动新建字段" value={name} onChange={onNameChange} />
                          <Typography.Link
                            onClick={(evt) => {
                              addItem(evt);
                            }}
                            style={{ whiteSpace: 'nowrap' }}
                          >
                            <PlusOutlined /> 增加
                          </Typography.Link>
                        </Space>
                        <Divider style={{ margin: '8px 0' }} />
                        {menu}
                      </>
                    )}
                    onChange={(value) => {
                      handleSave({ ...record, name: value });
                    }}
                  >
                    {levelMetadata[level.level]?.map((item: any) => (
                      <Option key={item.field_name} value={item.field_desc}>
                        {item.field_desc}
                      </Option>
                    ))}
                  </Select>
                )}
              />
              <Column
                title="操作"
                dataIndex="action"
                key="action"
                align="center"
                render={(_val, record: any) => (
                  <Button
                    type="link"
                    size="small"
                    danger
                    onClick={() => {
                      deleteItem(record.key);
                    }}
                  >
                    删除
                  </Button>
                )}
              />
            </Table>
          </TabPane>
        ))}
      </Tabs>
    </div>
  );
});

export default FieldCheck;
